#include <nir.h>
#include <Uart.h>		//串口底层驱动专用头文件
#include <stdio.h>

sbit IR_INPUT=P3^3;	//外部中断引脚   P33与键盘冲突，需要临时关闭键盘扫描
pdata unsigned char Uart_Sendx[20];	 // 串口接收数据储存数组 默认10个字节 若发送数据较长 可更改最大字节数

bit irflag=0;	//接收信号标志位
unsigned char ircode[4]={0,0,0,0};	//接收码值缓存区，按序存放，地址码，地址反码，键值码和键值反码

//红外接收初始化函数，定时器1用于高低电平计时，外部中断1用于检测边沿
void ISR_Init()
{
	IR_INPUT=1;		//初始化中断引脚，等待接收下降沿
	
	TMOD&=0x0F;
	TMOD|=0x10;		//定时器1为16位不可重装载模式
	AUXR &= 0xBF;    // 定时器1时钟12T模式
	
	TL1 = 0x00;      // 初始值0便于测量脉冲宽度
  TH1 = 0x00;
	
	IT1=1;	//外部中断1设为下边沿触发	
	EX1=1;	//外部中断1允许
}		

//void Timer1Init(void) {
//    AUXR &= 0xBF;    // 定时器1时钟12T模式
//    TMOD &= 0x0F;    // 清除定时器1模式位
//    TMOD |= 0x10;    // 设置为16位定时器模式
//    TL1 = 0x00;      // 初始值0便于测量脉冲宽度
//    TH1 = 0x00;
//    TR1 = 1;         // 启动定时器1
//    ET1 = 1;         // 使能定时器1中断
//    EA = 1;          // 开总中断
//}

//获取高电平时间
unsigned int GetHighTime()
{
	TH1=0;	//复位计数器
	TL1=0;
	TR1=1;	//打开定时器1
	while(IR_INPUT)
	{
		if(TH1>0x40)	//超出规定时间即信号有误，则不返回高电平时间
		{
			break;
		}
	}
	TR1=0;
	
	return(TH1*256+TL1);
}

//获取低电平时间
unsigned int GetLowTime()
{
	TH1=0;
	TL1=0;
	TR1=1;
	while(!IR_INPUT)
	{
		if(TH1>0x40)
		{
			break;
		}
	}
	TR1=0;
	
	return(TH1*256+TL1);
}


//外部中断1函数
void EXINT_ISR() interrupt 2
{
	unsigned char i, j;
	unsigned int _time;
	unsigned char byte;
	EX1=0;	//外部中断1关闭，防止多次调用
	
	//引导码确认
	_time=GetLowTime();	//先获取低电平，因为接收与发送电平相反
  //sprintf(Uart_Sendx, "1. %d\n", (unsigned int)time);
	//Uart_Send_String(Uart_Sendx);
 
	//if((time<7833)||(time>8755))	//12/11.0592*7833≈8500us,12/11.0592*8755≈9500us,协议规定9ms
	if((_time<8500)||(_time>9500))	//12/11.0592*7833≈8500us,12/11.0592*8755≈9500us,协议规定9ms
	{
		IE1=0;	//外部中断1标志位清零
		EX1=1;
		return;		//不在规定范围，引导码有误
	}
 
	
	_time = GetHighTime();
	
	
	//if((time<3686)||(time>4608))	//12/11.0592*3686≈4000us,12/11.0592*4608≈5000us，协议规定4.5ms
	if((_time<4000)||(_time>5000))	//12/11.0592*3686≈4000us,12/11.0592*4608≈5000us，协议规定4.5ms
	{
		IE1=0;
		EX1=1;
		return;
	}

	//，引导码正确，开始获取地址码，地址反码，键值码，键值反码并存入缓存区
	for(i=0;i<4;i++)
	{
		for(j=0;j<8;j++)
		{
			_time=GetLowTime();
 
//			if((time<313)||(time>718))	//推导与上述类似
			if((_time<400)||(_time>780))	//推导与上述类似
			{
				IE1=0;
				EX1=1;
				return;
			}
		
			_time=GetHighTime();
	
			//if((time>313)&&(time<718))
				if((_time>400)&&(_time<780))
			{
				byte>>=1;
			}
			else if((_time>1460)&&(_time<1900))// if((time>1345)&&(time<1751))
			{
				byte>>=1;
				byte|=0x80;
			}
			else
			{  
				IE1=0;
				EX1=1;
				return;
			}
		
		} 
		ircode[i]=byte;	//把获取到的8位码存入缓存数组
	
	}
	//	Uart_Send_String("end\n");
	irflag=1;//成功接收到码值
	IE1=0;
	EX1=1;	//外部中断1开启
}


